using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace WindowsGame
{
    /// <summary>
    /// This is a game component till keep track of score
    /// </summary>
    public class ScoreComponent : Microsoft.Xna.Framework.GameComponent
    {
        Game game;
        
        //For drawing font on screen
        SpriteFont hudFont;
        int curScore;
        Vector2 scorePosition;

        //String that will be passed and used to determine where to put animated strings
        String scoreString;

        //For animating score notification
        List<ScoreComponents.PointAnimator> animatorList;

        //Default color for string
        Color hudColor;

        //Sprite for HUD
        Texture2D hudSprite;
        Rectangle hudRectangle; //Rectangle for drawing HUD

        //Dimensions of screen
        int screenWidth, screenHeight;

        //Get other component
        PlayerComponent player;
        Camera2DComponent camera;

        Random rnd;

        public ScoreComponent(Game game, int screenWidth, int screenHeight, PlayerComponent player, Camera2DComponent camera)
            : base(game)
        {
            this.player = player;
            this.camera = camera;

            this.screenWidth = screenWidth;
            this.screenHeight = screenHeight;
            this.game = game;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            //Create a list for putting animator objects in, to be able to animate more than 1 object at a time
            animatorList = new List<ScoreComponents.PointAnimator>();

            //Set initial value for variables
            curScore = 0;
            scorePosition = new Vector2(5, 640);
            hudColor = Color.White;
            scoreString = "";

            //Initialize
            rnd = new Random();

            base.Initialize();
        }

        public void LoadContent(ContentManager Content)
        {
            //Load font
            hudFont = Content.Load<SpriteFont>("Fonts\\PressStart2P_12");

            //Load HUD
            hudSprite = Content.Load<Texture2D>("GFX\\HUD\\ScoreBarHUD");
            //Set rectangle after loading sprite to get right dimensions from actual sprite
            hudRectangle = new Rectangle(-hudSprite.Width, screenHeight - hudSprite.Height, hudSprite.Width, hudSprite.Height);


        }

        public override void Update(GameTime gameTime)
        {
            KeyboardState keyState = Keyboard.GetState();

            //Use score string to determine where to put animation later on also where to put HUD
            scoreString = "Score: " + curScore.ToString();

            //Calculate where to draw HUD. X value will be increased as the string for score gets longer
            if (hudRectangle.X + hudSprite.Width - 20 < hudFont.MeasureString(scoreString).X)
                hudRectangle.X = (int)hudFont.MeasureString(scoreString).X - hudSprite.Width + 20;

            //Update each entry in list
            for (int i = 0; i < animatorList.Count; i++)
                animatorList[i].Update(gameTime, this, i, scoreString, hudFont);

            base.Update(gameTime);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            //Sprite sort mode must be immediate for shaders to work
            spriteBatch.Begin();

            //Draw HUD
            spriteBatch.Draw(hudSprite, hudRectangle, Color.White);

            //Draw score string
            spriteBatch.DrawString(hudFont, scoreString, scorePosition, hudColor);
 
            spriteBatch.End();

            //Draw each entry in list
            for (int i = 0; i < animatorList.Count; i++)
                animatorList[i].Draw(spriteBatch, hudFont, camera);
        }

        public void AddPoints(int amount)
        {
            //Add passed amount to score
            curScore += amount;

            //Create a new temporarly animator and give needed information
            ScoreComponents.PointAnimator tempPointAnimator = new ScoreComponents.PointAnimator(this.game, player);
            tempPointAnimator.Initialize();

            //Old animation method
            //tempPointAnimator.SetPosition(new Vector2(scorePosition.X + 140, scorePosition.Y - 7));

            //New animation method. Set position by first locating player, then applying offset of a random value between -50 and 50
            tempPointAnimator.SetPosition(new Vector2(player.GetLocation().X + player.GetSize().X / 4 + rnd.Next(-50, 50), player.GetLocation().Y + player.GetSize().Y / 4 + rnd.Next(-50, 50)));
            tempPointAnimator.Animate(true, true);
            tempPointAnimator.SetAddedScoreAmount(amount);

            //Add animator to list
            animatorList.Add(tempPointAnimator);
        }

        public void RemovePoints(int amount)
        {
            //Check if score is going to be below 0. If that is the case, the score will be 0
            if (curScore - amount < 0)
                curScore = 0;
            else if (curScore > 0)
                curScore -= amount; //Remove passed amount if first statement is not fulfilled

            //Create a new temporarly animator and give needed information
            ScoreComponents.PointAnimator tempPointAnimator = new ScoreComponents.PointAnimator(this.game, player);
            tempPointAnimator.Initialize();

            //New animation method. Set position by first locating player, then applying offset of a random value between -50 and 50
            tempPointAnimator.SetPosition(new Vector2(player.GetLocation().X + player.GetSize().X / 4 + rnd.Next(-50, 50), player.GetLocation().Y + player.GetSize().Y / 4 + rnd.Next(-50, 50)));
            tempPointAnimator.Animate(false, true);
            tempPointAnimator.SetAddedScoreAmount(amount);

            //Add animator to list
            animatorList.Add(tempPointAnimator);
        }

        public void ResetScore()
        {
            //Sets the score to 0
            curScore = 0;
        }

        //Removes entry from animator list
        public void RemoveListEntry(int index) { animatorList.RemoveAt(index); }

        public Vector2 GetScorePosition() { return this.scorePosition; }
    }
}
